﻿// 项目：	Guan.CMS.Web - Guan.CMS
// 文件名：	AccountController.cs
// 
// 修改时间：2013-03-08 21:50
// 修改人：	Cooclsee

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using AutoMapper;
using Guan.CMS.CommandProcessor.Dispatcher;
using Guan.CMS.Core.Common;
using Guan.CMS.Data.Repositories;
using Guan.CMS.Domain.Commands.Account;
using Guan.CMS.Model.Entities;
using Guan.CMS.Web.Core.Authentication;
using Guan.CMS.Web.Core.Extensions;
using Guan.CMS.Web.Core.Models;
using Guan.CMS.Web.ViewModels;
namespace Guan.CMS.Web.Controllers
{
    [Authorize]
    public class AccountController : Controller
    {
        private readonly ICommandBus _commandBus;
        private readonly IUserRepository _userRepository;
        private readonly IFormsAuthentication _formAuthentication;

        public AccountController(ICommandBus commandBus,
                                 IUserRepository userRepository,
                                 IFormsAuthentication formsAuthentication)
        {
            this._commandBus = commandBus;
            this._userRepository = userRepository;
            this._formAuthentication = formsAuthentication;
        }

        //
        // GET: /Account/Login
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;
            return this.ContextDependentView();
        }

        //
        // POST: /Account/Login

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Login(LogOnFormModel form, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                User user = _userRepository.Get(u => u.UserName == form.UserName && u.Activated);
                if (user != null)
                {
                    if (ValidatePassword(user, form.Password))
                    {
                        //验证通过
                        _formAuthentication.SetAuthCookie(this.HttpContext,
                                                          UserAuthenticationTicketBuilder.CreateAuthenticationTicket(
                                                              user));
                        if (Url.IsLocalUrl(returnUrl))
                        {
                            return this.Redirect(returnUrl);
                        }
                        else
                        {
                            return RedirectToAction("Index", "Home");
                        }
                    }
                    else
                    {
                        ModelState.AddModelError("", "提供的用户名或密码不正确。");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "提供的用户名或密码不正确。");
                }
            }
            return this.View("Login", form);
        }

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public JsonResult JsonLogin(LogOnFormModel form, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                User user = _userRepository.Get(u => u.UserName == form.UserName && u.Activated);
                if (user != null)
                {
                    if (ValidatePassword(user, form.Password))
                    {
                        _formAuthentication.SetAuthCookie(this.HttpContext,
                                                          UserAuthenticationTicketBuilder.CreateAuthenticationTicket(
                                                              user));
                        return Json(new {success = true, redirect = returnUrl});
                    }
                    else
                    {
                        ModelState.AddModelError("", "提供的用户名或密码不正确。");
                    }
                }
            }
            return Json(new {errors = GetErrorsFromModelState(), success = false});
        }

        private IEnumerable<string> GetErrorsFromModelState()
        {
            return ModelState.SelectMany(x => x.Value.Errors.Select(error => error.ErrorMessage));
        }

        private bool ValidatePassword(User user, string password)
        {
            var encoded = Md5Encrypt.Md5EncryptPassword(password);
            return user.PasswordHash.Equals(encoded);
        }

        public ActionResult ChangePassword()
        {
            return this.View();
        }

        public ActionResult ChangePassword(ChangePasswordFormModel form)
        {
            if (ModelState.IsValid)
            {
                CmsUser cmsUser = HttpContext.User.GetCmsUser();
                var command = new ChangePasswordCommand
                {
                    UserId = cmsUser.UserId,
                    OldPassword = form.OldPassword,
                    NewPassword = form.NewPassword
                };
                IEnumerable<ValidationResult> errors = _commandBus.Validate(command);
                ModelState.AddModelErrors(errors);
                if (ModelState.IsValid)
                {
                    var result = _commandBus.Submit(command);
                    if (result.Success)
                    {
                        return RedirectToAction("ChangePasswordSuccess");
                    }
                    else
                    {
                        ModelState.AddModelError("", "当前密码错误或新密码非法。");
                    }
                }
            }
            return this.View(form);
        }

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        //
        // POST: /Account/LogOff
        public ActionResult LogOff()
        {
            _formAuthentication.Signout();
            return RedirectToAction("Index", "Home");
        }

        //
        // GET: /Account/Register
        [AllowAnonymous]
        public ActionResult Register()
        {
            return ContextDependentView();
        }

        private ActionResult ContextDependentView()
        {
            /*string actionName = ControllerContext.RouteData.GetRequiredString("action");
            if (Request.QueryString["content"] != null)
            {
                ViewBag.FormAction = "Json" + actionName;
                return this.PartialView();
            }
            else
            {
                ViewBag.FormAction = actionName;
                return this.View();
            }*/
            return this.View();
        }

        //
        // POST: /Account/Register

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Register(UserFormModel form)
        {
            if (ModelState.IsValid)
            {
                var command = Mapper.Map<UserFormModel, UserRegisterCommand>(form);
                command.Activated = true;
                command.RoleId = (Int32) UserRoles.User;
                IEnumerable<ValidationResult> errors = _commandBus.Validate(command);
                ModelState.AddModelErrors(errors);
                if (ModelState.IsValid)
                {
                    var result = _commandBus.Submit(command);
                    if (result.Success)
                    {
                        User user = _userRepository.Get(u => u.UserName == form.UserName);
                        _formAuthentication.SetAuthCookie(this.HttpContext,
                                                          UserAuthenticationTicketBuilder.CreateAuthenticationTicket(
                                                              user));
                        return RedirectToAction("Index", "Home");
                    }
                    else
                    {
                        ModelState.AddModelError("", "未知错误。");
                    }
                }
                return this.View(form);
            }
            return Json(new {errors = this.GetErrorsFromModelState()});
        }

        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // 请参见 http://go.microsoft.com/fwlink/?LinkID=177550 以查看
            // 状态代码的完整列表。
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "用户名已存在。请输入其他用户名。";

                case MembershipCreateStatus.DuplicateEmail:
                    return "该电子邮件地址的用户名已存在。请输入其他电子邮件地址。";

                case MembershipCreateStatus.InvalidPassword:
                    return "提供的密码无效。请输入有效的密码值。";

                case MembershipCreateStatus.InvalidEmail:
                    return "提供的电子邮件地址无效。请检查该值并重试。";

                case MembershipCreateStatus.InvalidAnswer:
                    return "提供的密码取回答案无效。请检查该值并重试。";

                case MembershipCreateStatus.InvalidQuestion:
                    return "提供的密码取回问题无效。请检查该值并重试。";

                case MembershipCreateStatus.InvalidUserName:
                    return "提供的用户名无效。请检查该值并重试。";

                case MembershipCreateStatus.ProviderError:
                    return "身份验证提供程序返回了错误。请验证您的输入并重试。如果问题仍然存在，请与系统管理员联系。";

                case MembershipCreateStatus.UserRejected:
                    return "已取消用户创建请求。请验证您的输入并重试。如果问题仍然存在，请与系统管理员联系。";

                default:
                    return "发生未知错误。请验证您的输入并重试。如果问题仍然存在，请与系统管理员联系。";
            }
        }

    }
}